﻿using CatLogLib;
using dll_CameraSelecter.ViewModels;
using Emgu.CV;
using MathFlowLib;
using Microsoft.Expression.Interactivity.Core;
using MvvmLib;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace LaserLineDetectorLib.ViewModel
{
    /// <summary>
    /// 调度类
    /// </summary>
    public class Vm_LaserLineDetector_Dispatch : Vm_Base
    {
        #region NotifyProperty

        /// <summary>
        /// 相机选择器
        /// </summary>
        public Vm_CameraSelecter CameraSelector
        {
            get { return _CameraSelector; }
            set
            {
                if (_CameraSelector != value)
                {
                    _CameraSelector = value;
                    this.OnPropertyChanged("CameraSelector");
                }
            }
        }
        private Vm_CameraSelecter _CameraSelector;

        /// <summary>
        /// 算法流
        /// </summary>
        public IMathFlow MathFlow
        {
            get { return _MathFlow; }
            set
            {
                if (_MathFlow != value)
                {
                    _MathFlow = value;
                    this.OnPropertyChanged("MathFlow");
                }
            }
        }
        private IMathFlow _MathFlow;


        /// <summary>
        /// 正在运行标志
        /// </summary>
        public bool IsWorking
        {
            get { return _IsWorking; }
            set
            {
                if (_IsWorking != value)
                {
                    _IsWorking = value;
                    this.OnPropertyChanged("IsWorking");
                }
            }
        }
        private bool _IsWorking;

        /// <summary>
        /// 当前图像
        /// </summary>
        public Mat MatImage
        {
            get { return _MatImage; }
            set
            {
                if (_MatImage != value)
                {
                    _MatImage = value;
                    this.OnPropertyChanged("MatImage");
                }
            }
        }
        private Mat _MatImage = new Mat();

        /// <summary>
        /// 算法结果
        /// </summary>
        public Vm_MathFlow_Line_Output MathFlow_Output
        {
            get { return _MathFlow_Output; }
            set
            {
                if (_MathFlow_Output != value)
                {
                    _MathFlow_Output = value;
                    this.OnPropertyChanged("MathFlow_Output");
                }
            }
        }
        private Vm_MathFlow_Line_Output _MathFlow_Output;

        /// <summary>
        /// 调度参数
        /// </summary>
        public Vm_LaserLineDetector_Dispatch_Param Param
        {
            get { return _Param; }
            set
            {
                if (_Param != value)
                {
                    _Param = value;
                    this.OnPropertyChanged("Param");
                }
            }
        }
        private Vm_LaserLineDetector_Dispatch_Param _Param;

        #endregion

        #region Command

        public ICommand Command_Attach { get; set; }
        public ICommand Command_Detach { get; set; }
        public ICommand Command_Start { get; set; }
        public ICommand Command_Stop { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="param"></param>
        public Vm_LaserLineDetector_Dispatch(Vm_LaserLineDetector_Dispatch_Param param)
        {
            //注入参数
            Param = param;

            //实例化对象
            CameraSelector = new Vm_CameraSelecter(Param.Param_CameraSelector);
            MathFlow = new Vm_MathFlow_Line(Param.Param_Line);
            MathFlow_Output = new Vm_MathFlow_Line_Output();

            //实例化命令
            Command_Attach = new ActionCommand(Attach);
            Command_Detach = new ActionCommand(Detach);
            Command_Start = new ActionCommand(Start);
            Command_Stop = new ActionCommand(Stop);

            //连接设备
            Attach();
        }


        /// <summary>
        /// 停止
        /// </summary>
        private void Stop()
        {
            if (IsWorking)
            {
                IsWorking = false;
                _ = workThread.Join(100);
            }
        }

        /// <summary>
        /// 开始
        /// </summary>
        private void Start()
        {
            if (IsWorking)
            {
                return;
            }

            IsWorking = true;
            workThread = new Thread(MeasureThread)
            {
                IsBackground = true
            };
            workThread.Start();
        }

        /// <summary>
        /// 工作线程
        /// </summary>
        private void MeasureThread()
        {
            while (IsWorking)
            {
                Vm_MathFlow_Output output = MathFlow_Output;

                output.MatImage = CameraSelector.Camera.Snap();

                try
                {
                    MathFlow.Run(output);
                }
                catch (Exception ex)
                {
                    CatLog.Log("调度", E_CatLogType.错误, "算法异常:" + ex.Message);
                }

                Application.Current.Dispatcher.Invoke(() =>
                {
                    MatImage = output.MatImage;
                });

                Thread.Sleep(30);
            }
        }

        /// <summary>
        /// 断开
        /// </summary>
        private void Detach()
        {
            try
            {
                if (!CameraSelector.Camera.Detach())
                {
                    throw new Exception("相机断开失败");
                }

                //取消订阅相机的图像获取事件
                CameraSelector.Camera.AcqImageEvent -= Camera_AcqImageEvent;

            }
            catch (Exception ex)
            {
                CatLog.Log("调度", E_CatLogType.错误, ex.Message);
            }

        }

        /// <summary>
        /// 连接
        /// </summary>
        private void Attach()
        {
            try
            {
                //相机
                if (CameraSelector == null)
                {
                    CameraSelector = new Vm_CameraSelecter(Param.Param_CameraSelector);
                }

                if (!CameraSelector.Camera.Attach())
                {
                    throw new Exception("相机连接失败");
                }

                //订阅相机的图像获取事件
                CameraSelector.Camera.AcqImageEvent += Camera_AcqImageEvent;
            }
            catch (Exception ex)
            {
                CatLog.Log("调度", E_CatLogType.错误, ex.Message);
            }

        }

        /// <summary>
        /// 相机图像获取事件响应方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="mat"></param>
        private void Camera_AcqImageEvent(object sender, Mat mat)
        {

        }

        #endregion


        #region Private

        private Thread workThread;

        #endregion
    }
}
